//
//  httpdownloadengine.m
//  Etion
//
//  Created by x w on 11-2-15.
//  Copyright 2011 GuangZhouXuanWu. All rights reserved.
//

#import "XLGDownloadManager.h"

#import "XLGDownloadOperation.h"

#import "XLGDownloadManagerInternal.h"

#import "XLGDownloadOperation+XLGDownloadOperationInternal.h"

@implementation XLGDownloadOperationCore

@synthesize delegateQueue = _delegateQueue;

-(id)init
{
    if (self = [super init])
    {
        self.dispatchQueueWrapper = [[[XMSDispatchQueueWrapper alloc]initWithName:""] autorelease_mm];
        _delegateQueue = [[XMSDispatchQueueWrapper alloc]initWithName:""];
    }
    return self;
}

-(void)dealloc
{
    [_delegateQueue release_mm];
    superdealloc_mm;
}

@end

@interface XLGDownloadOperation ()

@end

@implementation XLGDownloadOperation

@synthesize internalDelegate = _internalDelegate;
@synthesize mi = _mi;
@synthesize filePath = _filePath;
@synthesize arUIdelegate = _arUIdelegate;

-(id)initWithDownloadIndex:(XLGDownloadIndex *)mi
{
    self = [super init];
    
	_mi = [mi retain_mm];
    
    _arUIdelegate = [NSMutableArray new];

	_bFinish = NO;
    
	_fileCurrentSize=0;
	
//    _core = [[self createDownloadOperationCore] retain_mm];
    
    return self;
}

-(void)dealloc
{
	_bFinish = YES;
	[_filePath release_mm];
	[_mi release_mm];
	[_fileData release_mm];
    [_arUIdelegate release_mm];
    [_core release_mm];
    superdealloc_mm;
}

//-(void)refreshDownloadOperationPercent
//{
//    if(_item==nil)
//    {
//        _item=[XLGDownloadOperationItem new];
//        _item.extendID = _mi.m_szExtendid;
//        _item.URL = _mi.m_szContent;
//    }
//    _item.totalSize = _mi.m_nSender;
//    _item.writtenSize = _mi.m_nReceiver;
//    
//    [_core.delegateQueue dispatchThreadAsync:^
//    {
//        for(id<XLGDownloadOperationDelegate> delegate in _arUIdelegate)
//        {
//            [delegate refreshDownloadOperationItemPercent:_item];
//        }
//    }];
//}

-(void)addOperationDelegate:(id<XLGDownloadOperationDelegate>)delegate
{
    [self.core.delegateQueue dispatchThreadSync:^
    {
        if(delegate != nil && NO == [_arUIdelegate containsObject:delegate])
            [_arUIdelegate addObject:delegate];
    }];
}

-(void)addOperationDelegateFromArray:(NSArray*)arDelegate
{
    [self.core.delegateQueue dispatchThreadSync:^
    {
        for(id obj in arDelegate)
        {
            if(NO==[_arUIdelegate containsObject:obj])
                [_arUIdelegate addObject:obj];
        }
    }];
}

-(void)removeOperationDelegate:(id<XLGDownloadOperationDelegate>)delegate
{
    [self.core.delegateQueue dispatchThreadSync:^
    {
        [_arUIdelegate removeObject:delegate];
    }];
}

-(void)removeAllOperationdelegate
{
    [self.core.delegateQueue dispatchThreadSync:^
    {
        [_arUIdelegate removeAllObjects];
    }];
}

-(BOOL)startItem
{
    _bFinish = NO;
    _fileData = [NSMutableData new];
    _fileCurrentSize = 0;
    NSString* fileName = [_mi.URL lastPathComponent];
    if(_mi.storeName.length > 0)
    {
        if([_mi.storeName pathExtension].length > 0)
        {
            fileName = _mi.storeName;
        }
        else
        {
            fileName = [_mi.storeName stringByAppendingPathExtension:[fileName pathExtension]];
        }
    }
    _filePath = [[NSString stringWithFormat:@"%@/%@.%@",[[XLGDownloadManager downloadManager] defaultStorePath],fileName,[fileName pathExtension]] retain_mm];
    
    if(YES == [XMSFileHelper isFileExist:_filePath])
        _fileCurrentSize = [XMSFileHelper getFileSize:_filePath];
    
    return YES;
}

-(void)initFileData
{
    [_core dispatchQueueRunType:EDispatchQueueRunTypeAsync checkTerminate:YES asyncBlock:^
    {
        if(_mi.totalByte != 0 && _mi.totalByte != _fileTotalSize + _fileCurrentSize)
        {
            _mi.totalByte = _mi.downloadByte = 0;
            [_internalDelegate updateDownloadItem:_mi.extendID fileTotalByte:0 downloadByte:0];
            [XMSFileHelper deleteFileDir:_filePath];
            _fileCurrentSize = 0;
        }
        if(_fileCurrentSize <= 0)
        {
            _fileCurrentSize = 0;
            
            _mi.totalByte = _fileTotalSize;
            _mi.downloadByte = 0;
            
            [_internalDelegate updateDownloadItem:_mi.extendID fileTotalByte:_fileTotalSize downloadByte:_fileCurrentSize];
            
            NSFileManager * manager = [NSFileManager defaultManager];
            
            [manager createFileAtPath:_filePath contents:nil attributes:nil];
            
            _downloadFileHandle = [[NSFileHandle fileHandleForWritingAtPath:_filePath]retain_mm];
        }
        else
        {
            _downloadFileHandle = [[NSFileHandle fileHandleForWritingAtPath:_filePath]retain_mm];
            [_downloadFileHandle seekToEndOfFile];
        }
    }];
}

-(void)writeDataToFile:(NSData*)data
{
    [_core dispatchQueueRunType:EDispatchQueueRunTypeAsync checkTerminate:YES asyncBlock:^
    {
        [_fileData appendData:data];
        
        _fileCurrentSize += data.length;
        _mi.downloadByte = _fileCurrentSize;
        
        if(_fileData.length > FILEDATABUFFER || _fileCurrentSize >= _fileTotalSize)
        {
            [_downloadFileHandle writeData:_fileData];
            
        [_fileData resetBytesInRange:NSMakeRange(0, _fileData.length)];
        _fileData.length = 0;
        }
        
        [_core.delegateQueue dispatchThreadAsync:^
        {
            for(id<XLGDownloadOperationDelegate> delegate in _arUIdelegate)
            {
                [delegate downloadOperationItem:_mi.extendID refreshPercentWithFileTotalSize:_mi.totalByte downloadedSize:_mi.downloadByte];
            }
        }];
    }];
}

-(void)cleanup
{
    if(_fileData.length>0)
    {
        [_core dispatchQueueRunType:EDispatchQueueRunTypeSync checkTerminate:NO asyncBlock:^
        {
            if(_fileData.length>0)
                [_downloadFileHandle writeData:_fileData];
            ReleaseObj(_fileData);
        }];
    }
    
    ReleaseObj(_fileData);
	[_downloadFileHandle closeFile];
	ReleaseObj(_downloadFileHandle);
    _bFinish=YES;
    _fileCurrentSize = 0;
    ReleaseObj(_filePath);
    ReleaseObj(_core);
    
    [self stopItem];
}

-(void)stopDownload
{
    //0表示不更新totalSize
    [_internalDelegate updateDownloadItem:_mi.extendID fileTotalByte:0 downloadByte:_fileCurrentSize];
}

-(void)downloadFinished
{
    [_core dispatchQueueRunType:EDispatchQueueRunTypeAsync checkTerminate:YES asyncBlock:^
    {
        [_internalDelegate downloadOperation:self willFinishFileAssembly:nil];
        
        NSString* filepath = [self.filePath stringByDeletingPathExtension];
        [XMSFileHelper moveSource:self.filePath toTarget:filepath];
        
        [_internalDelegate downloadOperation:self didFinishFileAssembly:nil];
        
        [_internalDelegate downloadOperation:self endType:XLGDownloadEndTypeFinish];
        
        [self cleanup];
    }];
}

-(void)downloadError
{
    [_core dispatchQueueRunType:EDispatchQueueRunTypeAsync checkTerminate:YES asyncBlock:^
    {
        [_internalDelegate downloadOperation:self endType:XLGDownloadEndTypeError];
        
        [self cleanup];
    }];
}

@end
